#include <iostream>
#include <vector>
#include <filesystem>

using namespace std;

bool ConvertBinaryFileToTextFile(const std::string& BinaryFilePath,const std::string& TextFilePath)
{
    //1.read file content
    std::vector<uint8_t> BinaryFileContent;
    {
        FILE* BinaryFile=fopen(BinaryFilePath.c_str(),"rb");
        if(BinaryFile==nullptr)
        {
            std::cout<<"Can't open file "<<BinaryFilePath<<std::endl;
            return false;
        }

        fseek(BinaryFile,0,SEEK_END);
        size_t FileSize=ftell(BinaryFile);
        fseek(BinaryFile,0,SEEK_SET);

        BinaryFileContent.resize(FileSize);

        fread(BinaryFileContent.data(),1,FileSize,BinaryFile);

        fclose(BinaryFile);
    }

    //2.convert to text
    std::string TextFileContent;
    {
        TextFileContent.reserve(BinaryFileContent.size()*5);

        for(uint8_t Byte:BinaryFileContent)
        {
            char Hex[6];
            sprintf(Hex,"0x%02X,",Byte);
            TextFileContent+=Hex;
        }
    }

    //3.write to file
    {
        FILE* TextFile=fopen(TextFilePath.c_str(),"wb");
        if(TextFile==nullptr)
        {
            std::cout<<"Can't open file "<<TextFilePath<<std::endl;
            return false;
        }

        fwrite(TextFileContent.data(),1,TextFileContent.size(),TextFile);

        fclose(TextFile);
    }

    return true;
}


int main( int argc, char* argv[] )
{
    //first argument is bianry file directory
    //second argument is bianry file extension

    if(argc!=3)
    {
        std::cout<<"Usage: BinaryToText <binary file folder> <binary file extension>"<<std::endl;
        return -1;
    }

    std::string BinaryFilePath=argv[1];
    std::string BinaryFileExtension=argv[2]; 

    //check directory exist
    if(!std::filesystem::exists(BinaryFilePath))
    {
        std::cout<<"Directory "<<BinaryFilePath<<" not exist"<<std::endl;
        return -1;
    }

    //print start message
    std::cout<<"Converting all binary files in "<<BinaryFilePath<<" to text files"<<std::endl;

    //find all binary file
    std::vector<std::filesystem::path> BinaryFiles;
    {
        for(auto& File:std::filesystem::directory_iterator(BinaryFilePath))
        {
            if(File.is_regular_file())
            {
                //check file extension
                if(File.path().extension() == BinaryFileExtension)
                {
                    std::string TextFile=File.path().string();
                    TextFile+=".h";

                    //check if text file exist and is newer than binary file
                    if(std::filesystem::exists(TextFile))
                    {
                        if(std::filesystem::last_write_time(TextFile)>std::filesystem::last_write_time(File.path()))
                        {
                            continue;
                        }
                    }


                    BinaryFiles.push_back(File.path());
                }
            }
        }
    }

    //convert all binary file to text file
    for(auto& BinaryFile:BinaryFiles)
    {
        std::string TextFile=BinaryFile.string();
        TextFile+=".h";

        //std::cout<<"Converting "<<BinaryFile<<" to "<<TextFile<<std::endl;

        if(!ConvertBinaryFileToTextFile(BinaryFile.string(),TextFile))
        {
            return -1;
        }
    }

    //print end message
    std::cout<<"Converted "<<BinaryFiles.size()<<" files"<<std::endl;

    return 0;

}